home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / ghostscript / src / zcolor.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  9KB  |  334 lines

  1. /* Copyright (C) 1989, 1992, 1993 Aladdin Enterprises.  All rights reserved.
  2.  
  3. This file is part of Ghostscript.
  4.  
  5. Ghostscript is distributed in the hope that it will be useful, but
  6. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  7. to anyone for the consequences of using it or for whether it serves any
  8. particular purpose or works at all, unless he says so in writing.  Refer
  9. to the Ghostscript General Public License for full details.
  10.  
  11. Everyone is granted permission to copy, modify and redistribute
  12. Ghostscript, but only under the conditions described in the Ghostscript
  13. General Public License.  A copy of this license is supposed to have been
  14. given to you along with Ghostscript so you can know your rights and
  15. responsibilities.  It should be in a file named COPYING.  Among other
  16. things, the copyright notice and this notice must be preserved on all
  17. copies.  */
  18.  
  19. /* zcolor.c */
  20. /* Color operators for Ghostscript */
  21. #include "ghost.h"
  22. #include "errors.h"
  23. #include "oper.h"
  24. #include "alloc.h"
  25. #include "estack.h"
  26. #include "iutil.h"
  27. #include "store.h"
  28. #include "gxfixed.h"
  29. #include "gxmatrix.h"
  30. #include "gzstate.h"
  31. #include "gxdevice.h"            /* for gzcolor.h */
  32. #include "gzcolor.h"
  33. #include "state.h"
  34.  
  35. /* Import the 'for' operator */
  36. extern int
  37.   zfor(P1(os_ptr));
  38.  
  39. /* Define the number of estack slots needed for remap_one. */
  40. #define remap_one_estack 3
  41.  
  42. /* Forward declarations */
  43. private int remap_one(P3(const ref *, os_ptr, gx_transfer_map *));
  44. private int
  45.   remap_one_finish(P1(os_ptr)),
  46.   remap_color(P1(os_ptr));
  47.  
  48. /* Transfer functions for the library layer. */
  49. /* These just return what's already in the map. */
  50. #define tr_map(pgs,v,c)\
  51.   (pgs->transfer.c->values[(int)((v) * transfer_map_size + 0.5)] / frac_1_float)
  52. private float
  53. transfer_red(const gs_state *pgs, floatp value)
  54. {    return tr_map(pgs, value, red);
  55. }
  56. private float
  57. transfer_green(const gs_state *pgs, floatp value)
  58. {    return tr_map(pgs, value, green);
  59. }
  60. private float
  61. transfer_blue(const gs_state *pgs, floatp value)
  62. {    return tr_map(pgs, value, blue);
  63. }
  64. private float
  65. transfer_gray(const gs_state *pgs, floatp value)
  66. {    return tr_map(pgs, value, gray);
  67. }
  68. #undef tr_map
  69.  
  70. /* - currentblackgeneration <proc> */
  71. int
  72. zcurrentblackgeneration(register os_ptr op)
  73. {    push(1);
  74.     *op = istate.black_generation;
  75.     return 0;
  76. }
  77.  
  78. /* - currentcmykcolor <cyan> <magenta> <yellow> <black> */
  79. int
  80. zcurrentcmykcolor(register os_ptr op)
  81. {    float par[4];
  82.     gs_currentcmykcolor(igs, par);
  83.     push(4);
  84.     make_reals(op - 3, par, 4);
  85.     return 0;
  86. }
  87.  
  88. /* - currentcolortransfer <proc> */
  89. int
  90. zcurrentcolortransfer(register os_ptr op)
  91. {    push(4);
  92.     op[-3] = istate.transfer_procs.red;
  93.     op[-2] = istate.transfer_procs.green;
  94.     op[-1] = istate.transfer_procs.blue;
  95.     *op = istate.transfer_procs.gray;
  96.     return 0;
  97. }
  98.  
  99. /* - currentgray <gray> */
  100. int
  101. zcurrentgray(register os_ptr op)
  102. {    push(1);
  103.     make_real(op, gs_currentgray(igs));
  104.     return 0;
  105. }
  106.  
  107. /* - currenthsbcolor <hue> <saturation> <brightness> */
  108. int
  109. zcurrenthsbcolor(register os_ptr op)
  110. {    float par[3];
  111.     gs_currenthsbcolor(igs, par);
  112.     push(3);
  113.     make_reals(op - 2, par, 3);
  114.     return 0;
  115. }
  116.  
  117. /* - currentrgbcolor <red> <green> <blue> */
  118. int
  119. zcurrentrgbcolor(register os_ptr op)
  120. {    float par[3];
  121.     gs_currentrgbcolor(igs, par);
  122.     push(3);
  123.     make_reals(op - 2, par, 3);
  124.     return 0;
  125. }
  126.  
  127. /* - currenttransfer <proc> */
  128. int
  129. zcurrenttransfer(register os_ptr op)
  130. {    push(1);
  131.     *op = istate.transfer_procs.gray;
  132.     return 0;
  133. }
  134.  
  135. /* - currentundercolorremoval <proc> */
  136. int
  137. zcurrentundercolorremoval(register os_ptr op)
  138. {    push(1);
  139.     *op = istate.undercolor_removal;
  140.     return 0;
  141. }
  142.  
  143. /* - processcolors <int> - */
  144. /* Note: this is an undocumented operator that is not supported */
  145. /* in Level 2. */
  146. int
  147. zprocesscolors(register os_ptr op)
  148. {    push(1);
  149.     make_int(op, gs_currentdevice(igs)->color_info.num_components);
  150.     return 0;
  151. }
  152.  
  153. /* <proc> setblackgeneration - */
  154. /* INCOMPLETE */
  155. int
  156. zsetblackgeneration(register os_ptr op)
  157. {    check_proc(*op);
  158.     istate.black_generation = *op;
  159.     pop(1);
  160.     return 0;
  161. }
  162.  
  163. /* <cyan> <magenta> <yellow> <black> setcmykcolor - */
  164. int
  165. zsetcmykcolor(register os_ptr op)
  166. {    float par[4];
  167.     int code;
  168.     if (    (code = num_params(op, 4, par)) < 0 ||
  169.         (code = gs_setcmykcolor(igs, par[0], par[1], par[2], par[3])) < 0
  170.        )
  171.         return code;
  172.     make_null(&istate.colorspace.array);
  173.     pop(4);
  174.     return 0;
  175. }
  176.  
  177. /* <proc> setcolortransfer - */
  178. int
  179. zsetcolortransfer(register os_ptr op)
  180. {    int code;
  181.     check_proc(op[-3]);
  182.     check_proc(op[-2]);
  183.     check_proc(op[-1]);
  184.     check_proc(*op);
  185.     istate.transfer_procs.red = op[-3];
  186.     istate.transfer_procs.green = op[-2];
  187.     istate.transfer_procs.blue = op[-1];
  188.     istate.transfer_procs.gray = *op;
  189.     pop(4);  op -= 4;
  190.     check_estack(1 + remap_one_estack * 4);
  191.     push_op_estack(remap_color);
  192.     (code = gs_setcolortransfer_remap(igs, transfer_red, transfer_green, transfer_blue, transfer_gray, 0)) < 0 ||
  193.         /* Use osp rather than op here, because remap_one pushes. */
  194.     (code = remap_one(&istate.transfer_procs.red, osp, igs->transfer.red)) < 0 ||
  195.     (code = remap_one(&istate.transfer_procs.green, osp, igs->transfer.green)) < 0 ||
  196.     (code = remap_one(&istate.transfer_procs.blue, osp, igs->transfer.blue)) < 0 ||
  197.     (code = remap_one(&istate.transfer_procs.gray, osp, igs->transfer.gray)) < 0;
  198.     return code;
  199. }
  200.  
  201. /* <gray> setgray - */
  202. int
  203. zsetgray(register os_ptr op)
  204. {    float gray;
  205.     int code;
  206.     if ( (code = real_param(op, &gray)) < 0 ||
  207.          (code = gs_setgray(igs, gray)) < 0
  208.        )
  209.         return code;
  210.     make_null(&istate.colorspace.array);
  211.     pop(1);
  212.     return 0;
  213. }
  214.  
  215. /* <hue> <saturation> <brightness> sethsbcolor - */
  216. int
  217. zsethsbcolor(register os_ptr op)
  218. {    float par[3];
  219.     int code;
  220.     if (    (code = num_params(op, 3, par)) < 0 ||
  221.         (code = gs_sethsbcolor(igs, par[0], par[1], par[2])) < 0
  222.        )
  223.         return code;
  224.     make_null(&istate.colorspace.array);
  225.     pop(3);
  226.     return 0;
  227. }
  228.  
  229. /* <red> <green> <blue> setrgbcolor - */
  230. int
  231. zsetrgbcolor(register os_ptr op)
  232. {    float par[3];
  233.     int code;
  234.     if (    (code = num_params(op, 3, par)) < 0 ||
  235.         (code = gs_setrgbcolor(igs, par[0], par[1], par[2])) < 0
  236.        )
  237.         return code;
  238.     make_null(&istate.colorspace.array);
  239.     pop(3);
  240.     return 0;
  241. }
  242.  
  243. /* <proc> settransfer - */
  244. int
  245. zsettransfer(register os_ptr op)
  246. {    int code;
  247.     check_proc(*op);
  248.     istate.transfer_procs.red = istate.transfer_procs.green =
  249.       istate.transfer_procs.blue = istate.transfer_procs.gray = *op;
  250.     pop(1);  op--;
  251.     check_estack(1 + remap_one_estack);
  252.     code = gs_settransfer_remap(igs, transfer_gray, 0);
  253.     if ( code < 0 ) return code;
  254.     push_op_estack(remap_color);
  255.     return remap_one(&istate.transfer_procs.gray, op, igs->transfer.gray);
  256. }
  257.  
  258. /* <proc> setundercolorremoval - */
  259. /* INCOMPLETE */
  260. int
  261. zsetundercolorremoval(register os_ptr op)
  262. {    check_proc(*op);
  263.     istate.undercolor_removal = *op;
  264.     pop(1);
  265.     return 0;
  266. }
  267.  
  268. /* ------ Internal routines ------ */
  269.  
  270. /* Prepare to remap one color component. */
  271. /* Use the 'for' operator to gather the values. */
  272. /* The caller must have done the necessary check_estack. */
  273. private int
  274. remap_one(const ref *pproc, register os_ptr op, gx_transfer_map *pmap)
  275. {    push(4);
  276.     make_real(op - 3, 1.0);
  277.     make_real(op - 2, -0.999999 / (transfer_map_size - 1));
  278.     make_real(op - 1, 0.0);
  279.     *op = *pproc;
  280.     ++esp;
  281.     make_tasv(esp, t_string, 0, sizeof(*pmap), bytes, (byte *)pmap);
  282.     push_op_estack(remap_one_finish);
  283.     push_op_estack(zfor);
  284.     return o_push_estack;
  285. }
  286.  
  287. /* Store the result of remapping a component. */
  288. private int
  289. remap_one_finish(os_ptr op)
  290. {    int i;
  291.     gx_transfer_map *pmap = (gx_transfer_map *)esp->value.bytes;
  292.     for ( i = 0; i < transfer_map_size; i++ )
  293.        {    float v;
  294.         int code = real_param(op - i, &v);
  295.         if ( code < 0 ) return 0;
  296.         pmap->values[i] = gx_color_unit_param(v);
  297.        }
  298.     pop(transfer_map_size);
  299.     esp--;                /* pop pointer to transfer map */
  300.     return o_pop_estack;
  301. }
  302.  
  303. /* Finally, remap the current color. */
  304. private int
  305. remap_color(os_ptr op)
  306. {    return gx_remap_color(igs);
  307. }
  308.  
  309. /* ------ Initialization procedure ------ */
  310.  
  311. op_def zcolor_op_defs[] = {
  312.     {"0currentblackgeneration", zcurrentblackgeneration},
  313.     {"0currentcmykcolor", zcurrentcmykcolor},
  314.     {"0currentcolortransfer", zcurrentcolortransfer},
  315.     {"0currentgray", zcurrentgray},
  316.     {"0currenthsbcolor", zcurrenthsbcolor},
  317.     {"0currentrgbcolor", zcurrentrgbcolor},
  318.     {"0currenttransfer", zcurrenttransfer},
  319.     {"0currentundercolorremoval", zcurrentundercolorremoval},
  320.     {"0processcolors", zprocesscolors},
  321.     {"1setblackgeneration", zsetblackgeneration},
  322.     {"4setcmykcolor", zsetcmykcolor},
  323.     {"4setcolortransfer", zsetcolortransfer},
  324.     {"1setgray", zsetgray},
  325.     {"3sethsbcolor", zsethsbcolor},
  326.     {"3setrgbcolor", zsetrgbcolor},
  327.     {"1settransfer", zsettransfer},
  328.     {"1setundercolorremoval", zsetundercolorremoval},
  329.         /* Internal operators */
  330.     {"1%remap_one_finish", remap_one_finish},
  331.     {"0%remap_color", remap_color},
  332.     op_def_end(0)
  333. };
  334.